<template>
	<view class="yb-flex yb-flex-1" :style="{
		'position': 'relative',
		'background-color': optionsSync.bgColor,
	}">
		<view class="yb-file-list-footmarks yb-flex yb-justify-center" :style="{
			'background-color': optionsSync.bgColor
		}">
			<template v-if="editMode">
				<view class="yb-file-list-checks yb-flex yb-row yb-align-center yb-justify-between">
					<text class="yb-file-list-checks-text" :style="{color: optionsSync.titleColor}">已选择{{checkes.length}}个文件</text>
					<view class="yb-flex yb-row yb-align-center">
						<text class="yb-file-list-checks-text" :style="{color: optionsSync.titleColor, 'margin-right': '20rpx'}" @tap="itemsMenuShow = true">操作</text>
						<text class="yb-file-list-checks-text" :style="{color: optionsSync.titleColor}" @tap="closeEditMode">取消</text>
					</view>
				</view>
			</template>
			<template v-else>
				<yb-scroll-x ref="scrollX" custom-style="padding-left: 50rpx;padding-right: 50rpx;">
					<view class="yb-flex yb-row yb-align-center" :id="'mark' + i" v-for="(mark, i) in footmarks" :key="i" :style="{
						opacity: mark.path == nowPath ? 1 : 0.5
					}" @tap="openFolder(mark.path)">
						<text :style="{color: optionsSync.titleColor, 'font-size': '30rpx'}">{{mark.name}}</text>
						<yb-icon name="angle-arrow-right" size="30" :color="optionsSync.textColor" v-if="i < footmarks.length - 1"></yb-icon>
						<view style="width: 50rpx;" v-else></view>
					</view>
				</yb-scroll-x>
			</template>
		</view>
		<yb-gap size="70rpx"></yb-gap>
		<yb-list
		ref="list"
		type="page"
		custom-class="yb-flex-1"
		:loading="{
			show: loading,
			color: optionsSync.textColor,
			bgColor: optionsSync.bgColor
		}"
		:empty="{
			show: empty,
			color: optionsSync.textColor,
			bgColor: optionsSync.bgColor,
			title: '没有文件'
		}">
			<yb-list-item v-for="(item, index) in list" :key="index">
				<yb-tap active="mask" @tap="clickItem(item)" @longpress="onLongpress(item)"
				custom-class="yb-file-list yb-row yb-align-center" :custom-style="{'border-bottom-color': optionsSync.gapColor}">
					<view class="yb-file-list-icon yb-flex yb-align-center yb-justify-center">
						<slot :name="item.type">
							<list-icon :item="item"></list-icon>
						</slot>
					</view>
					<view class="yb-file-list-right yb-flex yb-flex-1 yb-justify-between">
						<view class="yb-flex">
							<text class="yb-file-list-title" :style="{'color': optionsSync.titleColor}">{{item.name}}</text>
							<text class="yb-file-list-text" :style="{'color': optionsSync.textColor}">{{item.time + ' - ' + item.size + (item.type == 'folder' ? '项' : '')}}</text>
						</view>
					</view>
					<yb-icon name="angle-arrow-right" size="30" :color="optionsSync.textColor" v-if="item.type=='folder'"></yb-icon>
					<yb-icon v-if="editMode && item.type !='folder'" :name="checkes.findIndex(check => check.path == item.path) > -1 ? 'check-circle-fill' : 'check-circle-no'" size="40rpx"
					:color="checkes.findIndex(check => check.path == item.path) > -1 ? '#2ca2f9' : optionsSync.textColor"></yb-icon>
				</yb-tap>
			</yb-list-item>
		</yb-list>
		<yb-popup direction="bottom" :visible.sync="itemsMenuShow">
			<view class="yb-file-list-panel yb-flex" :style="{'background-color': optionsSync.bgColor}">
				<scroll-view class="yb-file-list-panel-top" scroll-y="true" :style="{height: checkes.length > 6 ? '410rpx' : 'auto'}">
					<text class="yb-file-list-panel-name" :style="{color: optionsSync.titleColor, 'background-color': optionsSync.gapColor}" v-for="(item, index) in checkes" :key="index">{{item.name}}</text>
				</scroll-view>
				<view class="yb-flex yb-row yb-align-center">
					<view class="yb-file-list-panel-tool yb-flex yb-flex-1 yb-align-center yb-justify-center" @tap="selectAll">
						<yb-icon class="yb-file-list-panel-tool-icon" :name="checkes.length < fileLength ? 'check-rect-no' : 'check-rect-fill'" size="50" :color="optionsSync.textColor"></yb-icon>
						<text class="yb-file-list-panel-tool-name" :style="{color: optionsSync.titleColor}">{{checkes.length < fileLength ? '全选' : '全不选'}}</text>
					</view>
					<view class="yb-file-list-panel-tool yb-flex yb-flex-1 yb-align-center yb-justify-center" @tap="openFiles">
						<yb-icon class="yb-file-list-panel-tool-icon" name="file" size="50" :color="optionsSync.titleColor"></yb-icon>
						<text class="yb-file-list-panel-tool-name" :style="{color: optionsSync.titleColor}">打开</text>
					</view>
					<view class="yb-file-list-panel-tool yb-flex yb-flex-1 yb-align-center yb-justify-center" @tap="deleteFiles">
						<yb-icon class="yb-file-list-panel-tool-icon" name="dustbin" size="50" :color="optionsSync.titleColor"></yb-icon>
						<text class="yb-file-list-panel-tool-name" :style="{color: optionsSync.titleColor}">删除</text>
					</view>
					<view class="yb-file-list-panel-tool yb-flex yb-flex-1yb-flex-1 yb-align-center yb-justify-center" @tap="itemsMenuMoreShow = !itemsMenuMoreShow">
						<yb-icon class="yb-file-list-panel-tool-icon" name="more-horizontal" size="50" :color="optionsSync.titleColor"></yb-icon>
						<text class="yb-file-list-panel-tool-name" :style="{color: optionsSync.titleColor}">{{itemsMenuMoreShow ? '关闭' : '更多'}}</text>
					</view>
				</view>
				<scroll-view scroll-y="true" v-if="itemsMenuMoreShow" :style="{height: itemsMenus.length > 4 ? '300rpx' : 'auto'}">
					<text class="yb-file-list-panel-tool-line"
					:style="{color: optionsSync.titleColor, 'border-color': optionsSync.gapColor}"
					v-for="(menu, i) in itemsMenus" :key="i"
					@tap="menu.success(checkes)">{{menu.label}}</text>
				</scroll-view>
			</view>
		</yb-popup>
		<yb-notify ref="notify"></yb-notify>
		<yb-dialog ref="dialog"></yb-dialog>
	</view>
</template>

<script>
	// #ifdef APP-PLUS
	const environment = plus.android.importClass("android.os.Environment");
	const dom = weex.requireModule('dom');
	const rootPath = plus.android.invoke(environment.getExternalStorageDirectory(), 'getPath')
	// #endif
	let pages;
	let page;
	let backs;
	import ComponentMixin from '../../js_sdk/componentMixin.js'
	import ListIcon from './modules/list-icon.vue'
	import Util from '../../js_sdk/util.js'
	export default {
		mixins: [ComponentMixin],
		components: {
			ListIcon
		},
		props: {
			suffix: {
				type: String,
				default: ''
			},
			path: {
				type: String,
				default: ''
			},
			pageSize: {
				type: [Number, String],
				default: 10
			},
			itemsMenus: {
				type: Array,
				default () {
					return new Array
				}
			},
			options: {
				type: Object,
				default () {
					return new Object
				}
			},
			//是否允许多选
			multiple: {
				type: Boolean,
				default: true
			}
		},
		data () {
			return {
				footmarks: [],
				nowPath: '',
				loading: false,
				empty: false,
				list: [],
				fileLength: 0,
				checkes: [],
				editMode: false,//编辑模式
				itemsMenuShow: false,//展示编辑菜单
				itemsMenuMoreShow: false//展示更多编辑菜单
			}
		},
		computed: {
			Util () {
				return Util
			},
			optionsSync () {
				return Object.assign({}, {
					titleColor: '#333',
					textColor: '#999',
					gapColor: '#eee',
					bgColor: '#fff'
				}, this.options )
			}
		},
		mounted () {
			// #ifdef APP-PLUS
			this.requestPermissions()
			// #endif
			// #ifndef APP-PLUS
			this.$refs.notify.warning('该组件暂只支持APP-Android')
			// #endif
		},
		methods: {
			requestPermissions () {
				plus.android.requestPermissions(['android.permission.READ_EXTERNAL_STORAGE', 'android.permission.WRITE_EXTERNAL_STORAGE'],(e) =>{
					if(e.deniedAlways.length>0){	//权限被永久拒绝
						// 弹出提示框解释为何需要定位权限，引导用户打开设置页面开启
						this.$refs.dialog.confirm({
							title: {
								text: '提示',
								color: this.optionsSync.titleColor
							},
							content: {
								text: '访问本地文件需要存储权限：\n\n点击确认获取权限',
								color: this.optionsSync.textColor
							},
							options: {
								type: 1,
								bgColor: this.optionsSync.bgColor
							},
							success: (res) => {
								if ( res.confirm ) {
									this.requestPermissions()
								}
							}
						})
					}
					if(e.deniedPresent.length>0){	//权限被临时拒绝
						// 弹出提示框解释为何需要定位权限，可再次调用plus.android.requestPermissions申请权限
						this.$refs.dialog.confirm({
							title: {
								text: '提示',
								color: this.optionsSync.titleColor
							},
							content: {
								text: '访问本地文件需要存储权限：\n\n点击确认获取权限',
								color: this.optionsSync.textColor
							},
							options: {
								type: 1,
								bgColor: this.optionsSync.bgColor
							},
							success: (res) => {
								if ( res.confirm ) {
									this.requestPermissions()
								}
							}
						})
					}
					if(e.granted.length>0){	//权限被允许
					    //调用依赖获取定位权限的代码
						if( environment.getExternalStorageState() !== environment.MEDIA_MOUNTED ) {
							this.$refs.notify.fail('没有找到SD卡')
						} else {
							this.openFolder(this.path);
						}
					}
				}, function(e){
				    console.log('Request Permissions error:'+JSON.stringify(e));
				});
			},
			//打开文件
			open(params) {
				this.itemMenuShow = false
				let file = plus.android.newObject('java.io.File', params.path)
				if ( plus.android.invoke(file, 'exists') ) {
					this.$emit('itemClick', params)
				} else {
					this.$refs.notify.fail('文件路径失效')
					let index = this.list.findIndex(item => item.path == params.path)
					if ( index > -1 ) {
						this.list.splice(index, 1)
						this.fileLength--
					}
				}
			},
			//打开多个文件
			openFiles () {
				if ( this.checkes.length > 0 ) {
					this.$emit('itemsClick', this.checkes)
					this.closeEditMode()
				} else {
					this.$refs.notify.fail('未选择文件')
				}
			},
			//删除多个文件
			deleteFiles () {
				if ( this.checkes.length > 0 ) {
					let message = ''
					this.checkes.forEach((check, key) => {
						message += ((key + 1) + '.' + check.name + '\n\n')
					})
					this.$refs.dialog.confirm({
						title: {
							text: '提示',
							color: this.optionsSync.titleColor
						},
						content: {
							text: '删除以下文件：\n\n ' + message + '点击确认继续',
							color: this.optionsSync.textColor
						},
						options: {
							type: 1,
							bgColor: this.optionsSync.bgColor
						},
						success: (res) => {
							if ( res.confirm ) {
								this.$refs.dialog.hide()
								uni.showLoading({
									title: '删除中'
								})
								let errMessage = '';
								this.checkes.forEach(check => {
									let fd = plus.android.newObject('java.io.File', check.path);
									if (fd != null && plus.android.invoke(fd, 'exists')){
										let isDeleted = plus.android.invoke(fd, 'delete');
										//删除成功
										if ( isDeleted ) {
											let index = this.list.findIndex(item => item.path == check.path)
											if ( index > -1 ) {
												this.list.splice(index, 1)
												this.fileLength--
											}
										} else {
											//删除失败
											errMessage += (check.name + '\n\n')
										}
										
									} else {
										//文件不存在
										errMessage += (check.name + '\n\n')
										let index = this.list.findIndex(item => item.path == check.path)
										if ( index > -1 ) {
											this.list.splice(index, 1)
											this.fileLength--
										}
									}
								})
								uni.hideLoading()
								if ( !errMessage ) {
									this.$refs.notify.success('删除成功')
								} else {
									this.$refs.dialog.alert({
										title: {
											text: '提示',
											color: this.optionsSync.titleColor
										},
										content: {
											text: '以下文件删除失败: \n\n' + errMessage + '点击关闭',
											color: this.optionsSync.textColor
										},
										options: {
											type: 1,
											bgColor: this.optionsSync.bgColor
										}
									})
								}
								this.closeEditMode()
							}
						},
						fail: () => {
							console.log('fail');
						}
					})
				}
			},
			//重置为根目录
			reset () {
				this.openFolder();
			},
			//点击文件夹或文件访问
			clickItem (params) {
				if ( this.editMode && params.type != 'folder' ) {
					if ( this.multiple ) {
						let index = this.checkes.findIndex(check => check.path == params.path)
						if ( index == -1 ) {
							this.checkes.push(params)
						} else {
							this.checkes.splice(index, 1)
						}
					} else {
						this.checkes = []
						this.checkes.push(params)
					}
				} else {
					//如果是文件夹则访问文件列表
					if ( params.type == 'folder' ) {
						this.closeEditMode()
						this.openFolder(params.path);
						//如果是txt文件则进行阅读
					} else {
						this.open(params)
					}
				}
			},
			onLongpress (params) {
				if ( !this.editMode && params.type != 'folder' ) {
					this.checkes.push(params)
					this.editMode = true
				} 
			},
			//全选文件 /取消全选
			selectAll () {
				if ( !this.multiple ) return
				if ( this.checkes.length < this.fileLength ) {
					this.checkes = [];
					let len = this.list.length;
					for ( let i = 0; i < len; i++ ) {
						if ( this.list[i].type != 'folder' ) {
							this.checkes.push(this.list[i])
						}
					}
				} else {
					this.checkes = [];
				}
			},
			//选择文件
			check (params) {
				if ( !this.multiple ) return
				//如果为文件夹则不能选择
				if ( params.type == 'folder') {
					return;
				}
				let index = this.checkes.findIndex(item => item.path == params.path)
				index > -1 ? this.checkes.splice(index, 1) : this.checkes.push(params)
			},
			closeEditMode () {
				this.editMode = false
				this.checkes = []
				this.itemsMenuShow = false
				this.$refs.dialog.hide()
			},
			getParent (file) {
				let path = plus.android.invoke(file, 'getPath')
				let name = plus.android.invoke(file, 'getName')
				this.footmarks.unshift({
					path: path,
					name: path == rootPath ? '内部存储' : name
				})
				let parent = plus.android.newObject('java.io.File', plus.android.invoke(file, 'getParent'))
				if ( parent && plus.android.invoke(parent, 'exists') && path != rootPath ) {
					this.getParent(parent)
				}
			},
			//返回上级目录
			backParent () {
				let fd = plus.android.newObject('java.io.File', this.nowPath);
				if ( fd != null && plus.android.invoke(fd, 'exists') ) {
					let parent = plus.android.newObject('java.io.File', plus.android.invoke(file, 'getParent'))
					if ( parent && plus.android.invoke(parent, 'exists') && this.nowPath != rootPath ) {
						this.openFolder(plus.android.newObject('java.io.File', parent));
					} else {
						this.$refs.notify.warning('没有上级文件夹了')
					}
				} else {
					this.openFolder();
				}
			},
			//打开文件夹
			openFolder (path) {
				this.loading = true
				this.list = []
				this.$nextTick(function () {
					let file = plus.android.newObject('java.io.File', path)
					let fd = file && file != null && plus.android.invoke(file, 'exists') ? file : environment.getExternalStorageDirectory();
					this.nowPath = plus.android.invoke(fd, 'getPath')
					this.footmarks = []
					this.getParent(fd)
					this.$nextTick(function () {
						this.$refs.scrollX.scrollToElement('mark' + this.footmarks.findIndex(mark => mark.path == this.nowPath))
					})
					this.$emit('pathChange', this.nowPath);
					let list = plus.android.invoke(fd, 'listFiles');
					let len = list ? list.length : 0;
					let folder = [];
					let fileList = [];
					for(let i=0; i<len; i++){
					    // 过滤隐藏文件  
					    if ( !plus.android.invoke(list[i], 'isHidden') ){
							if ( plus.android.invoke(list[i], 'isDirectory') ){
								let name = plus.android.invoke(list[i], 'getName');
								let time = plus.android.invoke(list[i], 'lastModified');
								folder.push({
									name: name,
									type: 'folder',
									size: plus.android.invoke(list[i], 'listFiles').length,
									time: Util.dateFormat(time),
									createTime: time,
									path: plus.android.invoke(list[i], 'getPath')
								})
							} else {
								let name = plus.android.invoke(list[i],"getName");
								if ( (this.suffix && this.suffix.indexOf(Util.suffix(name)) > -1) || !this.suffix ) {
									let path = plus.android.invoke(list[i],"getPath");
									let time = plus.android.invoke(list[i],"lastModified");
									fileList.push({
										name: name,
										type: Util.suffix(name),
										size: this.readFileSize(list[i]),
										time: Util.dateFormat(time),
										createTime: time,
										path: path
									})
								}
							}
					    }
					}
					fileList.sort((a, b) => {
						return b.createTime - a.createTime;
					})
					this.fileLength = fileList.length
					this.list = folder.concat(fileList)
					this.loading = false
					this.empty = this.list.length == 0
					this.backTop();
					this.checkes = [];
				})
			},
			//返回顶部
			backTop () {
				this.$refs.list.backTop()
			},
			readFileSize (file) {
			    let fileSize = plus.android.newObject("java.io.FileInputStream", file);
				let available = plus.android.invoke(fileSize, 'available');
				let size = available != 'null' ? available : 0;
				let fileSizeString;
				if(size == 0){
					fileSizeString = "0B";
				}else if(size < 1024){
					fileSizeString = size + "B";
				}else if(size < 1048576){
					fileSizeString = (size/1024).toFixed(2) + "KB";
				}else if (size < 1073741824){
					fileSizeString = (size/1048576).toFixed(2) + "MB";
				}else{
					fileSizeString = (size/1073741824).toFixed(2) + "GB";
				}
				return fileSizeString;
			}
		},
		beforeDestroy () {
			clearTimeout(this.fileTimer)
			this.fileTimer = null
			page ? page.$vm.$options.onBackPress = backs : null
		},
		watch: {
			itemsMenuShow (newVal) {
				if ( newVal ) {
					this.itemsMenuMoreShow = false
					pages = getCurrentPages()
					page = pages[pages.length - 1]
					backs = page.$vm.$options.onBackPress//记录下当前页面有可能设置的返回事件监听方法，用于还原
					page.$vm.$options.onBackPress = new Array(0)
					page.$vm.$options.onBackPress.push((e) => {
						if ( this.itemsMenuShow ) {
							this.itemsMenuShow = false
							return true
						}
						return false
					})
				} else {
					page ? page.$vm.$options.onBackPress = backs : null
				}
			},
			editMode (newVal) {
				if ( newVal ) {
					pages = getCurrentPages()
					page = pages[pages.length - 1]
					backs = page.$vm.$options.onBackPress//记录下当前页面有可能设置的返回事件监听方法，用于还原
					page.$vm.$options.onBackPress = new Array(0)
					page.$vm.$options.onBackPress.push((e) => {
						if ( this.editMode ) {
							this.closeEditMode()
							return true
						}
						return false
					})
				} else {
					page ? page.$vm.$options.onBackPress = backs : null
				}
			}
		}
	}
</script>

<style scoped>
	.yb-file-list-footmarks {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		height: 70rpx;
		/* #ifndef APP-NVUE */
		z-index: 1;
		/* #endif */
	}
	.yb-file-list-checks {
		padding: 0 30rpx;
	}
	.yb-file-list-checks-text {
		font-size: 28rpx;
	}
	.yb-footmarks-scroll {
		padding: 0 50rpx;
		/* #ifndef APP-NVUE */
		overflow: unset;
		/* #endif */
	}
	.yb-file-list {
		border-bottom-width: 1px;
		border-bottom-style: solid;
		padding: 30rpx 50rpx;
	}
	.yb-file-list-icon {
		margin-right: 30rpx;
		width: 75rpx;
	}
	.yb-file-list-icon {
		width: 75rpx;
		height: 75rpx;
	}
	.yb-file-list-right {
		margin-right: 20rpx;
	}
	.yb-file-list-title {
		flex: 1;
		font-size: 30rpx;
		margin-bottom: 10rpx;
		/* #ifdef APP-NVUE */
		lines: 1;
		text-overflow: ellipsis;
		/* #endif */
		/* #ifndef APP-NVUE */
		display: -webkit-box !important;
		overflow: hidden;
		text-overflow: ellipsis;
		word-break: break-all;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 1;
		/* #endif */
	}
	.yb-file-list-text {
		font-size: 24rpx;
	}
	.yb-file-list-panel-top {
		/* #ifndef APP-NVUE */
		width: 100%;
		/* #endif */
	}
	.yb-file-list-panel-name {
		/* #ifndef APP-NVUE */
		display: block;
		/* #endif */
		text-align: center;
		padding: 20rpx;
		font-size: 25rpx;
	}
	.yb-file-list-panel-tool {
		flex: 1;
		padding: 20rpx 0;
	}
	.yb-file-list-panel-tool-icon {
		width: 50rpx;
		height: 50rpx;
	}
	.yb-file-list-panel-tool-name {
		font-size: 24rpx;
		margin-top: 10rpx;
		/* #ifdef APP-NVUE */
		lines: 1;
		text-overflow: ellipsis;
		/* #endif */
		/* #ifndef APP-NVUE */
		display: -webkit-box !important;
		overflow: hidden;
		text-overflow: ellipsis;
		word-break: break-all;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 1;
		/* #endif */
	}
	.yb-file-list-panel-tool-line {
		/* #ifndef APP-NVUE */
		display: block;
		/* #endif */
		text-align: center;
		font-size: 28rpx;
		border-top-width: 1px;
		border-top-style: solid;
		padding: 20rpx 0;
	}
</style>
